import { isUndefined, isNull, PagedList, PageParams, StringIndexer } from "mmb";
import * as brand_warehousepb from "../grpc-client/service/brand_warehouse_pb";
import { jsTimestampToPb, pbTimestampToJs } from "./helper";
import GrpcErrCode from "../grpc-client/grpcErrCode";
import AuditResult from "../bg-enums/auditResult";
import {
  getBgsBrandWarehouseOpSafely,
  getMetadata,
  getOptionsOfLight,
  wrapperGrpcError,
} from "../grpc-client/grpcAdapter";
import DeliveryMode from "../bg-enums/deliveryMode";
import StorageMode from "../bg-enums/storageMode";
import DataSource from "../bg-enums/dataSource";
import { SyncAction } from "../bg-enums/sync";
import {
  BrandWarehouse,
  CreateBrandWarehouseParams,
  UpdateBrandWarehouseParams,
} from "./declareTypes";

/****************************************************************************************/
/*                                   brand_warehouse entity                             */
/****************************************************************************************/

const brandWarehousePbToObject = (
  pb: brand_warehousepb.BrandWarehouseEntity
): BrandWarehouse => {
  return {
    brandWarehouseId: `${pb.getId()}`,
    brandId: `${pb.getBrandId()}`,
    name: pb.getName(),
    tel: pb.getTel(),
    linkman: pb.getLinkman(),
    address: pb.getAddress(),
    lng: pb.getLng(),
    lat: pb.getLat(),
    deliveryModes: pb.getDeliveryModesList().map((v) => v as DeliveryMode),
    cityCode: pb.getCityCode(),
    deadline: pb.getDeadline(),
    storageMode: pb.getStorageMode(),
    storeId: `${pb.getStoreId()}`,
    pStoreId: `${pb.getPStoreId()}`,
    permissionId: `${pb.getPermissionId()}`,
    remotePK: `${pb.getRemotePk()}`,
  };
};

/****************************************************************************************/
/*                                   brand_warehouse cmd                                */
/****************************************************************************************/

export const createBrandWarehouse = async ({
  brandId,
  name,
  tel,
  linkman,
  address,
  lng,
  lat,
  deliveryModes,
}: CreateBrandWarehouseParams): Promise<BrandWarehouse> => {
  const cl = getBgsBrandWarehouseOpSafely();
  const req = new brand_warehousepb.CreateBrandWarehouseRequest();
  req.setOrigin(DataSource.LOCAL);
  req.setBrandId(Number(brandId));
  req.setName(name);
  req.setTel(tel);
  req.setLinkman(linkman);
  req.setAddress(address);
  req.setLng(lng);
  req.setLat(lat);
  req.setDeliveryModesList(deliveryModes);

  // req.setCityCode(cityCode);
  // req.setRegionCode(regionCode);
  // req.setDeadline(deadline);
  // req.setStorageMode(storageMode);
  // req.setStoreId(Number(storeId));
  // req.setPStoreId(Number(pStoreId));
  // req.setPermissionId(Number(permissionId));

  return new Promise((resolve, reject) => {
    cl.createBrandWarehouse(
      req,
      getMetadata(),
      getOptionsOfLight(),
      (err, res) => {
        if (!isNull(err)) {
          reject(wrapperGrpcError(err.details));
          return;
        }
        const opRet = res.getOpRet()!;
        if (!opRet.getSuccess()) {
          reject(wrapperGrpcError(opRet.getMsg()));
          return;
        }
        resolve(brandWarehousePbToObject(res.getBrandWarehouse()!));
      }
    );
  });
};

export const updateBrandWarehouse = async ({
  brandWarehouseId,
  name,
  tel,
  linkman,
  address,
  lng,
  lat,
  deliveryModes,
}: UpdateBrandWarehouseParams): Promise<BrandWarehouse> => {
  const cl = getBgsBrandWarehouseOpSafely();
  const req = new brand_warehousepb.UpdateBrandWarehouseRequest();

  req.setId(Number(brandWarehouseId));
  req.setName(name);
  req.setTel(tel);
  req.setLinkman(linkman);
  req.setAddress(address);
  req.setLng(lng);
  req.setLat(lat);
  req.setDeliveryModesList(deliveryModes);
  // req.setCityCode(cityCode);
  // req.setRegionCode(regionCode);
  // req.setDeadline(deadline);
  // req.setStorageMode(storageMode);
  // req.setStoreId(Number(storeId));
  // req.setPStoreId(Number(pStoreId));
  // req.setPermissionId(Number(permissionId));


  return new Promise((resolve, reject) => {
    cl.updateBrandWarehouse(
      req,
      getMetadata(),
      getOptionsOfLight(),
      (err, res) => {
        if (!isNull(err)) {
          reject(wrapperGrpcError(err.details));
          return;
        }
        const opRet = res.getOpRet()!;
        if (!opRet.getSuccess()) {
          reject(wrapperGrpcError(opRet.getMsg()));
          return;
        }
        resolve(brandWarehousePbToObject(res.getBrandWarehouse()!));
      }
    );
  });
};

/****************************************************************************************/
/*                                   brand_warehouse query                        */
/****************************************************************************************/

export const getBrandWarehouse = async (
  brandWarehouseId: string
): Promise<BrandWarehouse> => {
  const cl = getBgsBrandWarehouseOpSafely();
  const req = new brand_warehousepb.GetBrandWarehouseRequest();

  req.setId(Number(brandWarehouseId));

  return new Promise((resolve, reject) => {
    cl.getBrandWarehouse(
      req,
      getMetadata(),
      getOptionsOfLight(),
      (err, res) => {
        if (!isNull(err)) {
          reject(wrapperGrpcError(err.details));
          return;
        }
        const opRet = res.getOpRet()!;
        if (!opRet.getSuccess()) {
          reject(wrapperGrpcError(opRet.getMsg()));
          return;
        }
        resolve(brandWarehousePbToObject(res.getBrandWarehouse()!));
      }
    );
  });
};

export const listBrandWarehousesByBrandID = async (
  brandId: string,
  pager: PageParams
): Promise<PagedList<BrandWarehouse>> => {
  const cl = getBgsBrandWarehouseOpSafely();
  const req = new brand_warehousepb.ListBrandWarehousesByBrandIDRequest();

  req.setLimit(pager.limit);
  req.setOffset(pager.offset);
  req.setBrandId(Number(brandId));

  return new Promise((resolve, reject) => {
    cl.listBrandWarehousesByBrandID(
      req,
      getMetadata(),
      getOptionsOfLight(),
      (err, res) => {
        if (!isNull(err)) {
          reject(wrapperGrpcError(err.details));
          return;
        }
        const opRet = res.getOpRet()!;
        if (!opRet.getSuccess()) {
          reject(wrapperGrpcError(opRet.getMsg()));
          return;
        }
        const ret: PagedList<BrandWarehouse> = {
          total: 0,
          items: [],
        };
        ret.total = res.getTotal();
        ret.items = res
          .getBrandWarehousesList()
          .map((u) => brandWarehousePbToObject(u));
        resolve(ret);
      }
    );
  });
};
